package com.hulei.studyproject.service;

import com.hulei.studyproject.entity.User;
import com.hulei.studyproject.threadpool.ThreadPoolUtil;
import com.hulei.studyproject.transaction.MultiThreadingTransactionManager;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 测试多线程事务回滚
 * @Title: UserServiceImpl
 * @Description: TODO
 * @author: hulei
 * @date: 2023/7/31 17:41
 * @Version: 1.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements IUserService{

    private final JdbcTemplate jdbcTemplate;

    private final PlatformTransactionManager platformTransactionManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insert() {
        System.out.println("主线程为:"+Thread.currentThread().getName());
        List<User> list = new ArrayList<>(){{
            add(new User("1","张三"));
        }};
        String sql = "insert into user(id,name) values (?,?)";
        jdbcTemplate.batchUpdate(sql,list, list.size(), (ps,d)->{
            ps.setString(1, d.getId());
            ps.setString(2,d.getName());
        });
        List<Runnable> runnableList = getRunnables();
        MultiThreadingTransactionManager multiThreadingTransactionManager = new MultiThreadingTransactionManager(platformTransactionManager,5, TimeUnit.SECONDS);
        ThreadPoolExecutor executor = ThreadPoolUtil.getThreadPool();
        multiThreadingTransactionManager.execute(runnableList,executor);
    }

    private List<Runnable> getRunnables() {
        List<Runnable> runnableList = new ArrayList<>();
        runnableList.add(()->{
            System.out.println("子线程1为:"+Thread.currentThread().getName());
            List<User> listOne = new ArrayList<>(){{
                add(new User("2","李四"));
            }};
            String sqlOne = "insert into user(id,name) values (?,?)";
            jdbcTemplate.batchUpdate(sqlOne,listOne, listOne.size(), (ps,d)->{
                ps.setString(1, d.getId());
                ps.setString(2,d.getName());
            });
            //int a = 10/0;
        });
        runnableList.add(()->{
            System.out.println("子线程2为:"+Thread.currentThread().getName());
            List<User> listTwo = new ArrayList<>(){{
                add(new User("3","王五"));
            }};
            String sqlTwo = "insert into user(id,name) values (?,?)";
            jdbcTemplate.batchUpdate(sqlTwo,listTwo, listTwo.size(), (ps,d)->{
                ps.setString(1, d.getId());
                ps.setString(2,d.getName());
            });
        });
        return runnableList;
    }
}
